#    Copyright 2008, 2009 Tri-County Electric Cooperative, St. Matthews, South Carolina
#    This file is part of COOPGIS.
#    COOPGIS is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#    COOPGIS is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#    You should have received a copy of the GNU General Public License
#    along with COOPGIS.  If not, see <http://www.gnu.org/licenses/>.

import os
import datetime
FTPFileName='/opt/coopgis/fromgps/anonymousftproot_OtherReadOnly/incomingftpallpermissions/Locations.csv'
import shutil

#************************BEGIN Add Include Files to Path************************
import sys
NeededPaths=['/opt/coopgis/djangoproject/include', '/opt/coopgis/djangoproject']
for path in NeededPaths:
    if(not path in sys.path):
        sys.path.append(path)
#************************END   Add Include Files to Path************************
from django.contrib.gis.geos import *
import os, time, psycopg2, datetime
#********************Setup psycopg2 and django section********************
PathDjangoRoot="/opt/coopgis/"
if(not PathDjangoRoot in sys.path):
    sys.path.append(PathDjangoRoot)
import djangoproject
from djangoproject.models import *
#********************Setup psycopg2 and django section********************
import COOPGIS_Ajax, COOPGIS_GPS, COOPGIS_Misc, COOPGIS_ReportLab, COOPGIS_String, COOPGIS_Update
from django.template import Context, loader
from django.http import HttpResponse
from django import forms
import os
import datetime
import djangoproject.settings


def ProcessCircuitTrace(form, UserName):
    """Traces a Circuit Downstream from the substation and highlights it on the map"""
    TraceMessage=''
    try:  
        CircuitToTrace=int(form.data['TraceCircuitNumber'])
    except:
        CircuitToTrace=None
    if(CircuitToTrace):
        circuitTrace=CircuitTrace()
        TraceMessage=circuitTrace.PerformTrace(CircuitToTrace, UserName)
    return TraceMessage

def ProcessGeoTrace(form, UserNameOrIPAddress):
    try:
        GeoTraceIndicator=bool(form.data['GeoTraceIndicator'] == 'on')
    except:
        GeoTraceIndicator=False
    try: 
        GeoTraceStartStationid=int(form.data['GeoTraceStartStationid'])
        GeoTraceStartStation=Station.objects.filter(id__exact=GeoTraceStartStationid)[0]
    except:
        GeoTraceStartStation=''
    try:
        GeoTraceFromCircuitNumber=int(form.data['GeoTraceFromCircuitNumber'])
    except:
        GeoTraceFromCircuitNumber=0
    try:
        GeoTraceToCircuitNumber=int(form.data['GeoTraceToCircuitNumber'])
    except:
        GeoTraceToCircuitNumber=0
    try: 
        GeoTraceSpanidsToStopAtString=form.data['GeoTraceSpanidsToStopAt']
        Temp=GeoTraceSpanidsToStopAtString.split(',')
        GeoTraceSpanidsToStopAt=[]
        for i in Temp:
            GeoTraceSpanidsToStopAt.append(int(i.strip()))
        GeoTraceSpansToStopAt=[]
        for i in Temp:
            try:
                GeoTraceSpansToStopAt.append(Span.objects.filter(id=i)[0])
            except:
                pass
    except:
        GeoTraceSpansToStopAt=[]
    try:
        GeoTraceConfirmChangeCircuit=str(form.data['GeoTraceConfirmChangeCircuit']).lower()
    except:
        GeoTraceConfirmChangeCircuit=''
    if(GeoTraceIndicator):
        trace=CircuitTrace()
        GeoTraceStations, GeoTraceSpans = trace.PerformGeoTrace(GeoTraceStartStation,  GeoTraceSpansToStopAt, UserNameOrIPAddress)
    else:
        GeoTraceStations=[]
        GeoTraceSpans=[]
    if(GeoTraceConfirmChangeCircuit == 'It is my circuit fault.'.lower() and GeoTraceStations and GeoTraceFromCircuitNumber):
        MassUpdateCircuitNumbers(UserNameOrIPAddress, GeoTraceStations, GeoTraceSpans, GeoTraceFromCircuitNumber, GeoTraceToCircuitNumber)
    try:
        GeoTraceConfirmChangeCompatibleUnit=str(form.data['GeoTraceConfirmChangeCompatibleUnit']).lower()
    except:
        GeoTraceConfirmChangeCompatibleUnit=''
    try:
        CompatibleUnitFromid=int(form.data['GeoTraceCompatibleUnitFrom'])
        compatibleUnitFrom=CompatibleUnit.objects.filter(id__exact=CompatibleUnitFromid)[0]
    except:
        compatibleUnitFrom=None
    try:
        CompatibleUnitToid=int(form.data['GeoTraceCompatibleUnitTo'])
        compatibleUnitTo=CompatibleUnit.objects.filter(id__exact=CompatibleUnitToid)[0]
    except:
        compatibleUnitTo=None
    if(GeoTraceConfirmChangeCompatibleUnit == 'It is my compatible unit fault.'.lower() and GeoTraceStations and compatibleUnitFrom and compatibleUnitTo):
        MassUpdateCompatibleUnits(UserNameOrIPAddress, GeoTraceStations, GeoTraceSpans, compatibleUnitFrom, compatibleUnitTo)
    try:
        GeoTraceConfirmChangePhase=str(form.data['GeoTraceConfirmChangePhase']).lower()
    except:
        GeoTraceConfirmChangePhase=''
    GeoTracePhaseNumberMap={}
    GeoTracePhaseNumberMap['-1'] = 'None'
    GeoTracePhaseNumberMap['1'] = 'A'
    GeoTracePhaseNumberMap['2'] = 'B'
    GeoTracePhaseNumberMap['3'] = 'C'
    GeoTracePhaseNumberMap['4'] = 'N'
    try:
        GeoTracePhaseNoneTo=GeoTracePhaseNumberMap[form.data['GeoTracePhaseNoneTo']]
    except:
        GeoTracePhaseNoneTo=GeoTracePhaseNumberMap['-1']
    try:
        GeoTracePhaseATo=GeoTracePhaseNumberMap[form.data['GeoTracePhaseATo']]
    except:
        GeoTracePhaseATo=GeoTracePhaseNumberMap['1']
    try:
        GeoTracePhaseBTo=GeoTracePhaseNumberMap[form.data['GeoTracePhaseBTo']]
    except:
        GeoTracePhaseBTo=GeoTracePhaseNumberMap['2']
    try:
        GeoTracePhaseCTo=GeoTracePhaseNumberMap[form.data['GeoTracePhaseCTo']]
    except:
        GeoTracePhaseCTo=GeoTracePhaseNumberMap['3']
    try:
        GeoTracePhaseNTo=GeoTracePhaseNumberMap[form.data['GeoTracePhaseNTo']]
    except:
        GeoTracePhaseNTo=GeoTracePhaseNumberMap['4']
    AnyPhasesToChange=False
    if(GeoTracePhaseNoneTo != 'None'):
        AnyPhasesToChange=True
    if(GeoTracePhaseATo != 'A'):
        AnyPhasesToChange=True
    if(GeoTracePhaseBTo != 'B'):
        AnyPhasesToChange=True
    if(GeoTracePhaseCTo != 'C'):
        AnyPhasesToChange=True
    if(GeoTracePhaseNTo != 'N'):
        AnyPhasesToChange=True
    if(GeoTraceConfirmChangePhase=='It is my phase fault.'.lower() and AnyPhasesToChange):
        MassUpdatePhases(UserNameOrIPAddress, GeoTraceStations, GeoTraceSpans, GeoTracePhaseNoneTo, GeoTracePhaseATo, GeoTracePhaseBTo, 
                         GeoTracePhaseCTo, GeoTracePhaseNTo)


def MassUpdateCircuitNumbers(UserName, Stations, Spans, FromCircuitNumber, ToCircuitNumber):
    AssembliesToEdit=[]
    for station in Stations:
        if(FromCircuitNumber == 9999):
            Assemblies=Assembly.objects.filter(Station=station)
        else:
            Assemblies=Assembly.objects.filter(Station=station).filter(CircuitNumber=FromCircuitNumber)
        for assembly in Assemblies:
            if(not assembly.CircuitNumber == ToCircuitNumber): 
                AssembliesToEdit.append(assembly)
    for span in Spans:
        if(FromCircuitNumber == 9999):
            Assemblies=Assembly.objects.filter(Span=span)
        else:
            Assemblies=Assembly.objects.filter(Span=span).filter(CircuitNumber=FromCircuitNumber)
        for assembly in Assemblies:
            if(not assembly.CircuitNumber == ToCircuitNumber): 
                AssembliesToEdit.append(assembly)
    for assembly in AssembliesToEdit:
        if(assembly.ResidesOnServerIndicator):
            command=Command()
            try:
                ManufacturerName=assembly.Manufacturer.Name
            except:
                ManufacturerName=None
            try:
                MeterFormName=assembly.MeterForm.Name
            except:
                MeterFormName=None
            try:
                OwnerName=assembly.AssemblyOwner.Name
            except:
                OwnerName=None
            try:
                MeterServiceTypeName=assembly.MeterServiceType.Name
            except:
                MeterServiceTypeName=None
            try:
                InstallStatusName=assembly.InstallStatus.Name
            except:
                InstallStatusName='Existing'
            try:
                StakerWorkOrderid=assembly.StakerWorkOrder.id
            except:
                StakerWorkOrderid=None
            command=command.Create(Name='EditAssembly', Assemblyid=assembly.id, AssemblyName=assembly.CompatibleUnit.Name,  
                                   TagNumber=assembly.TagNumber, PutIntoServiceDate=assembly.PutIntoServiceDate, 
                                   PrimaryIndicator=assembly.PrimaryIndicator,
                                   SecondaryIndicator=assembly.SecondaryIndicator, PoleStubIndicator=assembly.PoleStubIndicator, 
                                   PoleLightIndicator=assembly.PoleLightIndicator, PoleGuyIndicator=assembly.PoleGuyIndicator,
                                   PoleMeterIndicator=assembly.PoleMeterIndicator, OwnerName=OwnerName, 
                                   ManufacturerName=ManufacturerName, MeterFormName=MeterFormName, 
                                   OpenIndicator=assembly.OpenIndicator,  
                                   MeterOnPoleIndicator=assembly.MeterOnPoleIndicator, PhaseAIndicator=assembly.PhaseAIndicator, 
                                   PhaseBIndicator=assembly.PhaseBIndicator, PhaseCIndicator=assembly.PhaseCIndicator, 
                                   PhaseNeutralIndicator=assembly.PhaseNeutralIndicator, CircuitNumber=ToCircuitNumber,
                                   SerialNumber=assembly.SerialNumber, MeterNumber=assembly.MeterNumber, 
                                   MeterDCSINumber=assembly.MeterDCSINumber, SubstationName=assembly.SubstationName, 
                                   MapNumber=assembly.MapNumber, OldMapNumber=assembly.OldMapNumber,
                                   TransformerCompletelySelfProtectedIndicator=assembly.TransformerCompletelySelfProtectedIndicator,
                                   ServiceIndicator=assembly.ServiceIndicator, MeterServiceTypeName=MeterServiceTypeName, 
                                   CommandUserName=UserName, PhysicalAddress=assembly.PhysicalAddress, 
                                   IdleIndicator=assembly.IdleIndicator, InstallStatus=InstallStatusName, 
                                   StakerWorkOrderid=StakerWorkOrderid)
            command.Process()
        else: 
            command=Command.objects.filter(id=assembly.CreateCommand.id)[0]
            command.CompatibleUnit=assembly.CompatibleUnit
            command.CircuitNumber=ToCircuitNumber
            command.PhaseAIndicator=assembly.PhaseAIndicator
            command.PhaseBIndicator=assembly.PhaseBIndicator
            command.PhaseCIndicator=assembly.PhaseCIndicator
            command.PhaseNeutralIndicator=assembly.PhaseNeutralIndicator
            command.OpenIndicator=assembly.OpenIndicator
            command.save()
            assembly.CompatibleUnit=assembly.CompatibleUnit
            assembly.CircuitNumber=ToCircuitNumber
            assembly.PhaseAIndicator=assembly.PhaseAIndicator
            assembly.PhaseBIndicator=assembly.PhaseBIndicator
            assembly.PhaseCIndicator=assembly.PhaseCIndicator
            assembly.PhaseNeutralIndicator=assembly.PhaseNeutralIndicator
            assembly.OpenIndicator=assembly.OpenIndicator
            assembly.save()
            if(assembly.Station):
                assembly.Station.RebuildSymbology()
            else:
                assembly.Span.RebuildSymbology()

def MassUpdateCompatibleUnits(UserName, Stations, Spans, FromCompatibleUnit, ToCompatibleUnit):
    AssembliesToEdit=[]
    for station in Stations:
        Assemblies=Assembly.objects.filter(Station=station).filter(CompatibleUnit=FromCompatibleUnit)
        for assembly in Assemblies:
            AssembliesToEdit.append(assembly)
    for span in Spans:
        Assemblies=Assembly.objects.filter(Span=span).filter(CompatibleUnit=FromCompatibleUnit)
        for assembly in Assemblies:
            AssembliesToEdit.append(assembly)
    for assembly in AssembliesToEdit:
        if(assembly.ResidesOnServerIndicator):
            command=Command()
            try:
                ManufacturerName=assembly.Manufacturer.Name
            except:
                ManufacturerName=None
            try:
                MeterFormName=assembly.MeterForm.Name
            except:
                MeterFormName=None
            try:
                OwnerName=assembly.AssemblyOwner.Name
            except:
                OwnerName=None
            try:
                MeterServiceTypeName=assembly.MeterServiceType.Name
            except:
                MeterServiceTypeName=None
            try:
                InstallStatusName=assembly.InstallStatus.Name
            except:
                InstallStatusName='Existing'
            try:
                StakerWorkOrderid=assembly.StakerWorkOrder.id
            except:
                StakerWorkOrderid=None
       
            command=command.Create(Name='EditAssembly', Assemblyid=assembly.id, AssemblyName=ToCompatibleUnit.Name,  
                                   TagNumber=assembly.TagNumber, PutIntoServiceDate=assembly.PutIntoServiceDate, 
                                   PrimaryIndicator=assembly.PrimaryIndicator,
                                   SecondaryIndicator=assembly.SecondaryIndicator, PoleStubIndicator=assembly.PoleStubIndicator, 
                                   PoleLightIndicator=assembly.PoleLightIndicator, PoleGuyIndicator=assembly.PoleGuyIndicator,
                                   PoleMeterIndicator=assembly.PoleMeterIndicator, OwnerName=OwnerName, 
                                   ManufacturerName=ManufacturerName, MeterFormName=MeterFormName, 
                                   OpenIndicator=assembly.OpenIndicator,  
                                   MeterOnPoleIndicator=assembly.MeterOnPoleIndicator, PhaseAIndicator=assembly.PhaseAIndicator, 
                                   PhaseBIndicator=assembly.PhaseBIndicator, PhaseCIndicator=assembly.PhaseCIndicator, 
                                   PhaseNeutralIndicator=assembly.PhaseNeutralIndicator, CircuitNumber=assembly.CircuitNumber,
                                   SerialNumber=assembly.SerialNumber, MeterNumber=assembly.MeterNumber, 
                                   MeterDCSINumber=assembly.MeterDCSINumber, SubstationName=assembly.SubstationName,
                                   MapNumber=assembly.MapNumber, OldMapNumber=assembly.OldMapNumber,
                                   TransformerCompletelySelfProtectedIndicator=assembly.TransformerCompletelySelfProtectedIndicator,
                                   ServiceIndicator=assembly.ServiceIndicator, MeterServiceTypeName=MeterServiceTypeName, 
                                   CommandUserName=UserName, PhysicalAddress=assembly.PhysicalAddress, 
                                   IdleIndicator=assembly.IdleIndicator, InstallStatus=InstallStatusName, 
                                   StakerWorkOrderid=StakerWorkOrderid)
            command.Process()
        else: 
            command=Command.objects.filter(id=assembly.CreateCommand.id)[0]
            command.CompatibleUnit=ToCompatibleUnit
            command.CircuitNumber=ToCircuitNumber
            command.PhaseAIndicator=assembly.PhaseAIndicator
            command.PhaseBIndicator=assembly.PhaseBIndicator
            command.PhaseCIndicator=assembly.PhaseCIndicator
            command.PhaseNeutralIndicator=assembly.PhaseNeutralIndicator
            command.OpenIndicator=assembly.OpenIndicator
            command.save()
            assembly.CompatibleUnit=ToCompatibleUnit
            assembly.CircuitNumber=assembly.CircuitNumber
            assembly.PhaseAIndicator=assembly.PhaseAIndicator
            assembly.PhaseBIndicator=assembly.PhaseBIndicator
            assembly.PhaseCIndicator=assembly.PhaseCIndicator
            assembly.PhaseNeutralIndicator=assembly.PhaseNeutralIndicator
            assembly.OpenIndicator=assembly.OpenIndicator
            assembly.save()
            if(assembly.Station):
                assembly.Station.RebuildSymbology()
            else:
                assembly.Span.RebuildSymbology()


def MassUpdatePhases(UserName, Stations, Spans, PhaseNoneTo, PhaseATo, PhaseBTo, PhaseCTo, PhaseNTo):
    AssembliesToEdit=[]
    for station in Stations:
        Assemblies=Assembly.objects.filter(Station=station)
        for assembly in Assemblies:
            AssembliesToEdit.append(assembly)
    for span in Spans:
        Assemblies=Assembly.objects.filter(Span=span)
        for assembly in Assemblies:
            AssembliesToEdit.append(assembly)
    for assembly in AssembliesToEdit:
        CurrentPhasing = assembly.GetPhaseCode(GetNeutral=True)
        NewPhaseAIndicator=False
        NewPhaseBIndicator=False
        NewPhaseCIndicator=False
        NewPhaseNIndicator=False
        if(CurrentPhasing == ''):
            if(PhaseNoneTo == 'A'):
                NewPhaseAIndicator=True
            elif(PhaseNoneTo == 'B'):
                NewPhaseBIndicator=True
            elif(PhaseNoneTo == 'C'):
                NewPhaseCIndicator=True
            elif(PhaseNoneTo == 'N'):
                NewPhaseNIndicator=True
        if('A' in CurrentPhasing):
            if(PhaseATo == 'A'):
                NewPhaseAIndicator=True
            elif(PhaseATo == 'B'):
                NewPhaseBIndicator=True
            elif(PhaseATo == 'C'):
                NewPhaseCIndicator=True
            elif(PhaseATo == 'N'):
                NewPhaseNIndicator=True
        if('B' in CurrentPhasing):
            if(PhaseBTo == 'A'):
                NewPhaseAIndicator=True
            elif(PhaseBTo == 'B'):
                NewPhaseBIndicator=True
            elif(PhaseBTo == 'C'):
                NewPhaseCIndicator=True
            elif(PhaseBTo == 'N'):
                NewPhaseNIndicator=True
        if('C' in CurrentPhasing):
            if(PhaseCTo == 'A'):
                NewPhaseAIndicator=True
            elif(PhaseCTo == 'B'):
                NewPhaseBIndicator=True
            elif(PhaseCTo == 'C'):
                NewPhaseCIndicator=True
            elif(PhaseCTo == 'N'):
                NewPhaseNIndicator=True
        if('N' in CurrentPhasing):
            if(PhaseNTo == 'A'):
                NewPhaseAIndicator=True
            elif(PhaseNTo == 'B'):
                NewPhaseBIndicator=True
            elif(PhaseNTo == 'C'):
                NewPhaseCIndicator=True
            elif(PhaseNTo == 'N'):
                NewPhaseNIndicator=True
        if(assembly.ResidesOnServerIndicator):
            command=Command()
            try:
                ManufacturerName=assembly.Manufacturer.Name
            except:
                ManufacturerName=None
            try:
                MeterFormName=assembly.MeterForm.Name
            except:
                MeterFormName=None
            try:
                OwnerName=assembly.AssemblyOwner.Name
            except:
                OwnerName=None
            try:
                MeterServiceTypeName=assembly.MeterServiceType.Name
            except:
                MeterServiceTypeName=None
            try:
                InstallStatusName=assembly.InstallStatus.Name
            except:
                InstallStatusName='Existing'
            try:
                StakerWorkOrderid=assembly.StakerWorkOrder.id
            except:
                StakerWorkOrderid=None
            command=command.Create(Name='EditAssembly', Assemblyid=assembly.id, AssemblyName=assembly.CompatibleUnit.Name,  
                                   TagNumber=assembly.TagNumber, PutIntoServiceDate=assembly.PutIntoServiceDate, 
                                   PrimaryIndicator=assembly.PrimaryIndicator,
                                   SecondaryIndicator=assembly.SecondaryIndicator, PoleStubIndicator=assembly.PoleStubIndicator, 
                                   PoleLightIndicator=assembly.PoleLightIndicator, PoleGuyIndicator=assembly.PoleGuyIndicator,
                                   PoleMeterIndicator=assembly.PoleMeterIndicator, OwnerName=OwnerName, 
                                   ManufacturerName=ManufacturerName, MeterFormName=MeterFormName, 
                                   OpenIndicator=assembly.OpenIndicator, 
                                   MeterOnPoleIndicator=assembly.MeterOnPoleIndicator, PhaseAIndicator=NewPhaseAIndicator, 
                                   PhaseBIndicator=NewPhaseBIndicator, PhaseCIndicator=NewPhaseCIndicator, 
                                   PhaseNeutralIndicator=NewPhaseNIndicator, CircuitNumber=assembly.CircuitNumber,
                                   SerialNumber=assembly.SerialNumber, MeterNumber=assembly.MeterNumber, 
                                   MeterDCSINumber=assembly.MeterDCSINumber, SubstationName=assembly.SubstationName, 
                                   MapNumber=assembly.MapNumber, OldMapNumber=assembly.OldMapNumber,
                                   TransformerCompletelySelfProtectedIndicator=assembly.TransformerCompletelySelfProtectedIndicator,
                                   ServiceIndicator=assembly.ServiceIndicator, MeterServiceTypeName=MeterServiceTypeName, 
                                   CommandUserName=UserName, PhysicalAddress=assembly.PhysicalAddress, 
                                   IdleIndicator=assembly.IdleIndicator, InstallStatus=InstallStatusName, 
                                   StakerWorkOrderid=StakerWorkOrderid)
            command.Process()
        else: 
            command=Command.objects.filter(id=assembly.CreateCommand.id)[0]
            command.CompatibleUnit=assembly.CompatibleUnit
            command.CircuitNumber=ToCircuitNumber
            command.PhaseAIndicator=NewPhaseAIndicator
            command.PhaseBIndicator=NewPhaseBIndicator
            command.PhaseCIndicator=NewPhaseCIndicator
            command.PhaseNeutralIndicator=NewPhaseNIndicator
            command.OpenIndicator=assembly.OpenIndicator
            command.save()
            assembly.CompatibleUnit=assembly.CompatibleUnit
            assembly.CircuitNumber=assembly.CircuitNumber
            assembly.PhaseAIndicator=NewPhaseAIndicator
            assembly.PhaseBIndicator=NewPhaseBIndicator
            assembly.PhaseCIndicator=NewPhaseCIndicator
            assembly.PhaseNeutralIndicator=NewPhaseNIndicator
            assembly.OpenIndicator=assembly.OpenIndicator
            assembly.save()
            if(assembly.Station):
                assembly.Station.RebuildSymbology()
            else:
                assembly.Span.RebuildSymbology()
